-
Notifications
You must be signed in to change notification settings - Fork 713
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LADX: Fix generation error on minimal accessibility #4281
base: main
Are you sure you want to change the base?
Conversation
@Exempt-Medic You had a lot of issues with this. Could you peer review this? |
@threeandthreee also you should probably also see this |
I haven't been forced to look at fill stuff yet so I don't really understand how it works yet. Can't offer a particularly insightful review but it seems simple enough, thanks for looking into it. I'll put it into the next beta release and spend some time gaining understanding in case my review becomes necessary. |
I don't think this is correct in general. An all-state is a state that can (and has) reached every location in the multiworld (assuming there are no games with bugs that result in locations that are always unreachable). I think the state that should be used should collect all items from the item pool and all pre-fill items belonging to players other than the LADX player that is currently in Consider a dungeon where every location requires a I think most worlds don't collect the pre-fill items from other worlds when they do their |
Removing the victory item from the all-state does work to make pre_fill perform proper placement though. When sweeping for advancements, a |
I agree with the previous comments. To give a concrete example why the solution is not perfect yet, I added the following plando block:
This is an incredibly bad plando, because you need the Tail Key to reach the location, so this always break. |
Here is my proposed solution: on minimal accessibility: Here are several cases, some of which give intended errors.
This is the "correct" error; these items need to be in the dungeon, but cannot be made accessible, which violates the full accessibility setting.
This is a custom error. The items were all successfully placed. Some are not accessible, that that is fine because of minimal accessibility. However, with these placements, the game is not beatable. This error is only intended to occur when plando asks for impossible seeds.
The unreachable items are intended because you can never enter Tail Cave because the Tail Key is plandod in there. |
The point still stands that a full all-state cannot be used with My understanding is that the I think a correct all-state, that does not include the dungeon items being placed, can be constructed like this. # Set up state
partial_all_state = CollectionState(self.multiworld)
# Collect every item from the item pool and every pre-fill item like MultiWorld.get_all_state, but don't sweep.
for item in self.itempool:
partial_all_state.collect(item, prevent_sweep=True)
for player in self.multiworld.player_ids:
subworld = self.worlds[player]
for item in subworld.get_pre_fill_items():
partial_all_state.collect(item, prevent_sweep=True)
# get_all_state would normally sweep here, but we need to remove our dungeon items first.
# Remove dungeon items we are about to put in from the state so that we don't double count
for item in all_dungeon_items_to_fill:
partial_all_state.remove(item)
# Sweep to pick up already placed items that are reachable with everything but the dungeon items.
partial_all_state.sweep_for_advancements() |
First let me paste your code that works for me, I had to change a few things (add .multiworld twice iirc) because I was getting errors.
This code seems to work (too)! I will have to think about what the differences are, if any. |
I'm not sure what the differences are, but your code also has all intended results and succeeded 1000 random yamls! |
Ah, whoops, I was copying code from What's being fixedThis partial all-state fixes cases where there are pre-placed (plando-ed or otherwise) items at locations locked behind items in The problem with get_all_stateThe state from Removing the items in The partial all-stateInstead, when creating the fill_restrictive
These steps repeat until either There's a bit more too it than that because it's slightly different when there is more than one player, and there's also 'swap' which can be used to try to fix placements when I think it would be perfectly fine to still allow Minimal Accessibility to do a |
should probably just skip your own pre_fill_items() instead of collect+remove them imo also since it's a single player placement do you even need to collect any pre_fill_items? |
I haven't been able to look at this PR anymore since my last comment, I'm also perhaps not knowledgable enough anymore since the solution was expanded upon a lot. |
from #4281 (comment)
@qwint does this not address the reason to collect pre fill items? I really appreciate the detailed explanations Mysteryem. Its a lot so I don't pretend to fully understand but it was a huge help. Your reasoning makes sense to me and the current pr fixes the issue so this has my approval as is (for whatever value that currently has 😀). There may be adjustments available but I don't really want to hold this up for them since its a functioning fix for a pretty big bug. |
that does answer my side comment of "why collect other world's pre fill items" but not "why collect+remove your own instead of just skipping your world when iterating over pre_fill_items" |
Unless I'm misunderstanding something it's only our dungeon items getting removed. Wouldn't we still want our pre fills for the same reason we want everyone else's? |
are you pre filling outside of prefill? everything that should be in that list should either be filled by now or be the items you are currently filling |
I'm not certain I understood you in the first place so let me back up. In the current PR are you saying that we should be skipping our own world while setting up If so, I don't understand why we would do that. As Mysteryem explained, we're setting up |
get_pre_fill_items is meant to return the items a world places in pre_fill so that an all state constructed before pre_fill completes can contain all the items that will eventually be placed (because they are not in start inventory, itempool, or on filled locations, the places where all state can check) if you are in your own pre_fill all relevant items should already be placed (since this is the last step of your pre_fill) or in itempool/start inventory, any items not fitting those categories should be items that you are going to place in the restrictive fill using that all state, so if you have them duplicated they can cause erroneous fills (the whole reason why you're removing at all) and if they are somehow not in any of those groups they shouldn't be in your pre_fill_items and are likely not relevant to fill anyways (since they would never get placed in that case) |
I think all the dungeon items to place in # Set up state
partial_all_state = CollectionState(self.multiworld)
# Collect every item from the item pool and every pre-fill item like MultiWorld.get_all_state, except not our own pre-fill items.
for item in self.multiworld.itempool:
partial_all_state.collect(item, prevent_sweep=True)
for player in self.multiworld.player_ids:
if player == self.player:
# Don't collect the items we're about to place.
continue
subworld = self.multiworld.worlds[player]
for item in subworld.get_pre_fill_items():
partial_all_state.collect(item, prevent_sweep=True)
# Sweep to pick up already placed items that are reachable with everything but the dungeon items.
partial_all_state.sweep_for_advancements() If they are the same, then it does then question if creating |
That makes sense now, thank you |
What is this fixing or adding?
This fixes the consistent generation error on minimal accessibility, which was caused by calling fill_restrictive with a state including
An Alarm Clock
, which is the victory item.The solution makes the correct state to apply
fill_restrictive
with dungeons to.How was this tested?
I've tried several scenarios (see one of my comments), I also did 1000 generations on purely random settings without issues.